﻿IF EXISTS (SELECT * FROM dbo.sysobjects WHERE id = OBJECT_ID(N'[proc_EjecutaSorteoPorFechas]') AND OBJECTPROPERTY(id,N'IsProcedure') = 1)
    DROP PROCEDURE proc_EjecutaSorteoPorFechas;
GO
/*
Idea:
	- Recibe rango de fechas
	- Extrae las promociones que estan vigentes en el rango
	- Saca las acciones de esas promociones y las pone en una tabla temporal con identity
		
	- Verifica que hayan suficientes concursantes para sorteo

	- Calcula un rand entre min y max  #Ganadores veces
	- si ganador es valido (no repetido si se restringe) entonces lo marca como ganador
	- Al finalizar ciclo marca sorteo como ejecutado
	- returna lista de acciones ganadoras denormalizada con el participante para desplegarla	
*/ 
CREATE PROCEDURE [proc_EjecutaSorteoPorFechas]
	@fechaInicial AS DATETIME,
	@fechaFinal AS DATETIME,
	@totalGanadores AS INT,		
	@favorecerMultiplesVeces AS INT
AS
BEGIN

	SET NOCOUNT ON			

	DECLARE	@participantesDisponibles	AS INT,
			@numGanadores				AS INT,
			@numAcciones				AS INT,	
			@accionGanadora				AS INT			
	DECLARE @acciones TABLE (Id INT IDENTITY, AccionId INT, numeroAccion INT, participanteId INT, gano BIT)

	INSERT @acciones (AccionId, numeroAccion, participanteId, gano)
	SELECT a.id, numeroAccion, participanteId, 0
	FROM accion a
	INNER JOIN Promocion p ON a.promocionId = p.Id
	WHERE	p.FechaInicio <= @fechaFinal 
	AND		p.FechaFinal >= @fechaInicial

	SELECT @numAcciones = COUNT(*) FROM @acciones
	
	IF @numAcciones = 0
	BEGIN
		RAISERROR ('No existen promociones en el rango de fechas o no se han cargado participantes', 16, 1)		
		RETURN
	END	

	SELECT @participantesDisponibles = COUNT(distinct participanteId)
	FROM @acciones

	IF @participantesDisponibles < @totalGanadores
	BEGIN
		RAISERROR ('No hay suficientes participantes cargados para ejecutar sorteo', 16, 1)		
		RETURN
	END

	SELECT	@numGanadores = 1

	WHILE @numGanadores <= @totalGanadores
	BEGIN
		SELECT @accionGanadora = CAST(@numAcciones * RAND() + 1 AS INT)
		
		IF NOT EXISTS(	SELECT Id
						FROM @acciones
						WHERE participanteId = (SELECT participanteId FROM @acciones WHERE Id = @accionGanadora)
						AND	  Gano = 1) OR @favorecerMultiplesVeces = 1 	
		BEGIN
			UPDATE @acciones SET Gano = 1 WHERE id = @accionGanadora		
			UPDATE Accion 
			SET Ganador = 1 
			WHERE Id = (SELECT accionId FROM @acciones WHERE Id = @accionGanadora)

			SET @numGanadores = @numGanadores + 1
		END
	END
		
	SELECT a.AccionId Accion, p.Nombre, p.Cedula, p.Telefono, p.Empresa
	FROM @acciones a
	INNER JOIN participante p ON a.participanteId = p.Id
	WHERE a.Gano = 1
		
END
GO

